 package com.inspur.edp.bef.bizentity.util;


 import com.inspur.edp.bef.bizentity.GspBizEntityElement;
 import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityErrorCodeEnum;
 import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityException;
 import com.inspur.edp.cef.designtime.api.IGspCommonField;
 import com.inspur.edp.cef.designtime.api.collection.GspAssociationCollection;
 import com.inspur.edp.cef.designtime.api.element.GspAssociation;
 import com.inspur.edp.cef.designtime.api.element.GspAssociationKey;
 import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
 import com.inspur.edp.cef.designtime.api.element.GspEnumValue;
 import com.inspur.edp.cef.designtime.api.entity.MappingInfo;
 import com.inspur.edp.cef.designtime.api.entity.MappingRelation;
 import com.inspur.edp.das.commonmodel.IGspCommonElement;
 import com.inspur.edp.das.commonmodel.entity.element.GspCommonAssociation;
 import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
 import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
 import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
 import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnInfo;
 import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType;
 import com.inspur.edp.udt.designtime.api.entity.element.UdtElement;
 import com.inspur.edp.udt.designtime.api.entity.enumtype.UseType;
 import lombok.var;

 import java.util.UUID;

 /**
  更新udt字段
 
 */
 public class UpdateBeElementUtil
 {
 	/**
 	 创建字段实例
	 
 	 @return
 	*/
 	private GspBizEntityElement GetChildElement()
 	{
 		GspBizEntityElement tempVar = new GspBizEntityElement();
 		tempVar.setID(UUID.randomUUID().toString());
 		return tempVar;
 	}

 	/**
 	 根据引用的udt元数据更新字段(模板约束均更新)
	 
 	 @param element
 	 @param udt
 	*/
 //ORIGINAL LINE: public void updateElementWithRefUdt(GspBizEntityElement element, UnifiedDataTypeDef udt, bool isFirstChoose = false)
 	public final void updateElementWithRefUdt(GspBizEntityElement element, UnifiedDataTypeDef udt, boolean isFirstChoose)
 	{
 		element.setUdtID(udt.getId());
 		element.setUdtName(udt.getName());

 		Object tempVar = element.getMappingRelation().clone();

 		var mappingInfos = (MappingRelation)((tempVar instanceof MappingRelation) ? tempVar : null);

 		var childElements = element.getChildElements().clone(null, null);

 		element.getMappingRelation().clear();
 		element.getChildElements().clear();

 		if (udt.getColumns().size() > 0)
 		{

			for (ColumnInfo col : udt.getColumns())
			{

				String columnInfoId = col.getID();
				MappingInfo mappingInfo=new MappingInfo();
				GspBizEntityElement childElement=new GspBizEntityElement();
				if (mappingInfos != null && mappingInfos.getValues().contains(columnInfoId))
				{
					// ① childElement已存在，更新；
					for (MappingInfo info:mappingInfos){
						if(info.getValueInfo().equals(columnInfoId)){
							mappingInfo=info;
							break;
						}
					}
					String childElementId = mappingInfo.getKeyInfo();
					for(IGspCommonField commonField:childElements){
						if (commonField.getID().equals(childElementId)){
							childElement=(GspBizEntityElement)((commonField instanceof GspBizEntityElement) ? commonField : null);
							break;
						}
					}
					if (childElement==null)
					{
						throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0068, childElementId, "childElement");
					}
				}
				else
				{
					// ② 新增
					childElement = GetChildElement();
					MappingInfo tempVar3 = new MappingInfo();
					tempVar3.setKeyInfo(childElement.getID());
					tempVar3.setValueInfo(columnInfoId);
					mappingInfo = tempVar3;
				}
				// 根据columnInfo更新childElement
				MapColumnInfoToField(col, element.getLabelID(), childElement);

				element.getMappingRelation().add(mappingInfo);
				element.getChildElements().add(childElement);
			}
 		}

		// 字段设置为udt,清空已有标记，带出当前单值udt的标记
		if (element.getBeLabel() != null && element.getBeLabel().size() > 0)
		{
			element.getBeLabel().clear();
		}

 		// 其他属性
 		if (udt instanceof ComplexDataTypeDef)
 		{
 			updateComplexDataTypeDefProperties(element, (ComplexDataTypeDef)udt);
 		}
 		else  if(udt instanceof SimpleDataTypeDef )
 		{
			updateSimpleDataTypeDefProperties(element, (SimpleDataTypeDef)udt, isFirstChoose);
 		}
 	}

 	/**
 	 转换columnInfo为childElement
	 
 	 @param info
 	 @param prefix
 	 @param ele 映射字段
 	 @return
 	*/
 	public final void MapColumnInfoToField(ColumnInfo info, String prefix, GspBizEntityElement ele)
 	{
 		if (StringUtil.checkNull(prefix))
 		{
			throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0069);
 		}

 		var newLabelId = prefix + "_" + info.getCode();
 		ele.setLabelID(newLabelId);
 		ele.setCode( newLabelId);
 		ele.setName(info.getName());
 		ele.setMDataType(info.getMDataType());
 		ele.setDefaultValue(info.getDefaultValue());
 		ele.setLength(info.getLength());
 		ele.setPrecision(info.getPrecision());
 	}


 		//#region 单值

 	/**
 	 根据单值udt更新字段的其他属性
	 
 	 @param element
 	 @param sUdt
 	 @param isFirstChoose 是否首次选择
 	*/
 	private void updateSimpleDataTypeDefProperties(GspBizEntityElement element, SimpleDataTypeDef sUdt, boolean isFirstChoose)
 	{
 		if (StringUtil.checkNull(element.getCode()))
 		{
 			element.setCode( sUdt.getCode());
 		}
 		if (StringUtil.checkNull(element.getName()))
 		{
 			element.setName(sUdt.getName());
 		}

 		if (isFirstChoose || isConstraint(sUdt, "DataType"))
 		{
 			element.setMDataType(sUdt.getMDataType());
 		}
 		if (isFirstChoose || isConstraint(sUdt, "Length"))
 		{
 			element.setLength(sUdt.getLength());
 		}
 		if (isFirstChoose || isConstraint(sUdt, "Precision"))
 		{
 			element.setPrecision(sUdt.getPrecision());
 		}
 		if (isFirstChoose || isConstraint(sUdt, "ObjectType"))
 		{
 			element.setObjectType(sUdt.getObjectType()) ;
 			// 关联
 			if (element.getChildAssociations() == null)
 			{
 				element.setChildAssociations(new GspAssociationCollection() );
 			}

 			var belongElement = (element.getChildAssociations() != null && element.getChildAssociations().size() > 0) ? element.getChildAssociations().get(0).getBelongElement() : null;

 			var assos = element.getChildAssociations().clone(belongElement);

 			element.getChildAssociations().clear();
 			if (sUdt.getChildAssociations() != null && sUdt.getChildAssociations().size() > 0)
 			{
 				for (GspAssociation item : sUdt.getChildAssociations())
 				{

// 					var beAsso = assos.Find(asso { return asso.Id == item.Id);
 					GspAssociation beAsso=assos.stream().filter((asso)->{
 						return item.getId().equals(asso.getId());
					}).findFirst().orElse(null);
 					element.getChildAssociations().add(convertUdtAssociation(item, element, beAsso, isFirstChoose));
 				}
 			}

 			element.setEnumIndexType(sUdt.getEnumIndexType());
 			// 枚举
 			element.getContainEnumValues().clear();
 			if (sUdt.getContainEnumValues() != null && sUdt.getContainEnumValues().size() > 0)
 			{
 				for (GspEnumValue item : sUdt.getContainEnumValues())
 				{
 					element.getContainEnumValues().add(item);
 				}
 			}
 		}
 		if (isFirstChoose || isConstraint(sUdt, "DefaultValue"))
 		{
 			element.setDefaultValue((sUdt.getDefaultValue()==null) ? null:sUdt.getDefaultValue().toString());
 		}
 		if (isFirstChoose || isConstraint(sUdt, "IsRequired"))
 		{
 			element.setIsRequire(sUdt.getIsRequired());
 		}
 		// 标记
 		element.setBeLabel(sUdt.getBeLabel());
 	}
 	/**
 	 是否约束
	 
 	 @return
 	*/
 	private boolean isConstraint(SimpleDataTypeDef sUdt, String propertyName)
 	{
 		if (sUdt.getPropertyUseTypeInfos().containsKey(propertyName))
 		{

 			var type = sUdt.getPropertyUseTypeInfos().get(propertyName);
 			return type.getPropertyUseType() == UseType.AsConstraint;
 		}
 		else
 		{
			throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0080, propertyName);
 		}
 	}


 		//#endregion


 		//#region 多值
 	/**
 	 根据多值udt更新字段的其他属性
	 
 	 @param element
 	 @param cUdt
 	*/
 	private void updateComplexDataTypeDefProperties(GspBizEntityElement element, ComplexDataTypeDef cUdt)
 	{
 		if (StringUtil.checkNull(element.getCode()))
 		{
 			element.setCode( cUdt.getCode());
 		}
 		if (StringUtil.checkNull(element.getName()))
 		{
 			element.setName(cUdt.getName());
 		}

 		UdtElement newElement;
 		if (cUdt.getElements().size() == 1 && cUdt.getDbInfo().getMappingType() != ColumnMapType.SingleColumn)
 		{
 			newElement = (UdtElement)cUdt.getElements().get(0);
 		}
 		else
 		{
 			newElement = new UdtElement(cUdt.getPropertys());
 		}

 		element.setObjectType(newElement.getObjectType());
 		// 若为[单一列]的映射关系，可能导致超长，需把数据类型改为[Text]
 		if (cUdt.getDbInfo().getMappingType() == ColumnMapType.SingleColumn)
 		{
 			element.setMDataType(GspElementDataType.Text);
 			element.setLength(0);
 			element.setPrecision(0);
 		}
 		else
 		{
 			element.setMDataType(newElement.getMDataType());
 			element.setLength(newElement.getLength());
 			element.setPrecision(newElement.getPrecision());
 		}
 		element.setDefaultValue(newElement.getDefaultValue());
 		element.getChildAssociations().clear();
 		element.getContainEnumValues().clear();
 	}

 		//#endregion


 		//#region 关联
 	private GspAssociation convertUdtAssociation(GspAssociation udtAsso, IGspCommonElement ele, GspAssociation beAsso, boolean isFirstChoose)
 	{
		GspCommonAssociation asso = new GspCommonAssociation();
 		asso.setId(udtAsso.getId());
 		asso.setRefModel((ele.getBelongObject()==null) ? null: ele.getBelongObject().getBelongModel());
 		asso.setRefModelCode(udtAsso.getRefModelCode());
 		asso.setRefModelID(udtAsso.getRefModelID());;
 		asso.setRefModelName(udtAsso.getRefModelName());
 		asso.setRefModelPkgName(udtAsso.getRefModelPkgName());
 		asso.setRefObjectCode(udtAsso.getRefObjectCode());
 		asso.setRefObjectID(udtAsso.getRefObjectID());
 		asso.setRefObjectName(udtAsso.getRefObjectName());
 		asso.setForeignKeyConstraintType(udtAsso.getForeignKeyConstraintType());
 		asso.setAssoModelInfo(udtAsso.getAssoModelInfo());
 		if (udtAsso.getKeyCollection().size() > 0)
 		{
 			for (GspAssociationKey key : udtAsso.getKeyCollection())
 			{
 				asso.getKeyCollection().add(convertUdtAssoKey(key, ele));
 			}
 		}

 		if (isFirstChoose)
 		{
 			if (udtAsso.getRefElementCollection().size() > 0)
 			{
 				for (IGspCommonField refEle : udtAsso.getRefElementCollection())
 				{
					IGspCommonElement newRefEle=convertUdtRefElement((UdtElement)refEle, ele.getLabelID());
					newRefEle.setBelongObject(ele.getBelongObject());
					asso.getRefElementCollection().add(newRefEle);
 				}
 			}
 		}
 		else
 		{

 			var udtRefElements = udtAsso.getRefElementCollection().clone(null, udtAsso);
 			// udt带出
 			if (beAsso != null && beAsso.getRefElementCollection() != null && beAsso.getRefElementCollection().size() != 0)
 			{
 				for (IGspCommonField refEle : beAsso.getRefElementCollection())
 				{
 					if (refEle.getIsFromAssoUdt())
 					{
						IGspCommonField refElement =udtRefElements.stream().filter((item)->{
							return item.getRefElementId().equals(refEle.getRefElementId());
						}).findFirst().orElse(null);
// 						var refElement = udtRefElements.f.Find(item { return item.RefElementId == refEle.getRef);
 						udtRefElements.remove(refElement);
 						// udt仍包含，则加上；udt上已删，则不加。
 						if (refElement != null)
 						{
 							IGspCommonElement refEle2 = convertUdtRefElement((UdtElement)refElement, ele.getLabelID());
 							refEle2.setID(refEle.getID());
 							refEle2.setBelongObject(ele.getBelongObject());
 							asso.getRefElementCollection().add(refEle2);
 						}
 					}
 					else
 					{
 						asso.getRefElementCollection().add(refEle);
 					}
 				}
 			}
 			if (udtRefElements.size() > 0)
 			{
 				for (IGspCommonField refEle : udtRefElements)
 				{
 					asso.getRefElementCollection().add(convertUdtRefElement((UdtElement)((refEle instanceof UdtElement) ? refEle : null), ele.getLabelID()));
 				}
 			}
 		}

 		return asso;
 	}

 	private GspAssociationKey convertUdtAssoKey(GspAssociationKey udtKey, IGspCommonElement ele)
 	{
 		GspAssociationKey key = new GspAssociationKey();
 		key.setSourceElement(udtKey.getSourceElement());
 		key.setSourceElementDisplay(udtKey.getSourceElementDisplay());
 		key.setTargetElement(ele.getID());
 		key.setTargetElementDisplay(ele.getName());
 		return key;
 	}

 	private IGspCommonElement convertUdtRefElement(UdtElement udtEle, String prefix)
 	{
 		GspBizEntityElement bizEle = new GspBizEntityElement();
 		//bizEle.getID() = udtEle.getID();

 		var newLabelId = prefix + "_" + udtEle.getLabelID();
 		bizEle.setLabelID(newLabelId);
 		bizEle.setCode( udtEle.getCode());
 		bizEle.setName(udtEle.getName());
 		bizEle.setMDataType(udtEle.getMDataType());
 		bizEle.setObjectType(udtEle.getObjectType() );
 		bizEle.setLength(udtEle.getLength());
 		bizEle.setPrecision(udtEle.getPrecision());
 		bizEle.setRefElementId(udtEle.getRefElementId());
 		bizEle.setIsRefElement(true);
 		bizEle.setIsFromAssoUdt(true);

 		// udt相关
 		bizEle.setIsUdt(udtEle.getIsUdt());
 		bizEle.setUdtID(udtEle.getUdtID());
 		bizEle.setUdtName(udtEle.getUdtName());
 		bizEle.setUdtPkgName(udtEle.getUdtPkgName());
 		switch (udtEle.getObjectType())
 		{
 			case Enum:
 				bizEle.setContainEnumValues(udtEle.getContainEnumValues());
 				break;
 		}
 		return bizEle;
 	}

 		//#endregion
 }